# -*- coding: utf-8 -*-

from openerp.osv import osv, fields
import datetime
import random
from openerp.tools.translate import _
from openerp import models, SUPERUSER_ID
"""
继承产品模板对象：添加本项目中的一些标志性的字段
is_card：标识这个产品是卡券产品。pass_length：卡券产品有密码字段，这个字段用于规定密码的长度。
subsidy_costs：门店补助费用是为了标识这个产品是否经过维护。act_id：每个卡券产品都必须对应一个卡券的激活产品，这个是用来绑定对应的产品。（卡券激活产品是为了方便以后的激活的方便）
weixin_card_id：是为了标识，这个字段是否是微信卡券ID
"""


class product_template(osv.osv):
    _inherit = "product.template"
    _columns = {
        'is_card': fields.boolean(u'卡券产品', help="卡券产品"),
        'pass_length': fields.integer(u'密码位数', help="密码位数"),
        'subsidy_costs': fields.float(u'门店补助费用'),
        'act_id': fields.many2one('product.product', u'激活服务产品', on_delete="restrict"),
        'weixin_card_id': fields.char(u'微信卡券ID', help="微信卡券ID"),
    }
    _defaults = {
        'pass_length': 8
    }

# 继承产品模板的创建方法：
# 在创建产品模板时，要先判断一下创建的产品是否是卡券产品，如果是就创建对应的卡券激活产品（active：False是为了隐藏该卡券激活产品，避免人为操作的失误）
# 并且把创建的卡券激活产品对应的ID添加到本产品中。
    def create(self, cr, uid, vals, context=None):
        aid = False
        if vals.get('is_card') and vals.get('type') != 'service':
            aid = self.pool.get('product.product').create(cr, uid, {
                'name': vals.get('name') + u'激活',
                'type': 'service',
                'active': False,
            }
            )
            if aid:
                self.pool.get('product.product').browse(cr, uid, aid, context).product_tmpl_id.write(
                    {'active': False, 'is_card': True, 'type': 'service'})
                vals.update({'act_id': aid})
        tid = super(product_template, self).create(
            cr, uid, vals, context=context)
        return tid

# 继承产品模板的修改方法：
# 是为了避免在创建时忘记勾选是卡券产品。而在修改时勾选是卡券产品，这时也应该创建对应的卡券激活产品
# 这个方法并不会删除已有的卡券激活产品。
    def write(self, cr, uid, ids, vals, context=None):
        aid = False
        product_obj = self.browse(cr, uid, ids, context=context)
        if vals.get('is_card') and product_obj.act_id.id == False and vals.get('type') != 'service':
            aid = self.pool.get('product.product').create(cr, uid, {
                'name': product_obj.name + u'激活',
                'type': 'service',
                'active': False,
            }
            )
            if aid:
                self.pool.get('product.product').browse(cr, uid, aid, context).product_tmpl_id.write(
                    {'active': False, 'is_card': True, 'type': 'service'})
                vals.update({'act_id': aid})
        tid = super(product_template, self).write(
            cr, uid, ids, vals, context=context)
        return tid


#修改产品的名称显示
class product_product(osv.Model):
    _inherit = 'product.product'

    def name_get(self, cr, user, ids, context=None):
        #res = super(product_product, self).name_get(cr, user, ids, context=context)
        res = [(product.id, product.name) for product in self.browse(cr, user, ids, context=context)]
        return res

"""
# 卡券发行、入库、批量启用禁用表
# 禁用的卡券不能出售，可退回
主要定义了卡券批量操作的常用标识字段.和一些批量操作中的方法。

"""


class product_card_issue(osv.osv):
    _name = "product.card.issue"
    _description = u"卡券批量操作表"
    _columns = {
        'name': fields.char(u'操作批次', required=True),
        'product_id': fields.many2one('product.product', u'产品', required=True, domain="['&',('is_card','=', True),'&',('act_id','!=',''),'&',('sale_ok','=',True),('active','=',True)]"),
        'number_start': fields.char(u'起始券号', required=True),
        'number_end': fields.char(u'结束券号', readonly=True),
        'quantity': fields.integer(u'卡券数量', required=True),
        'card_list': fields.text(u'券号列表'),
        'is_suffix': fields.boolean(u'有后缀8'),
        'suffix_val': fields.char(u'后缀'),
        'operation_type': fields.selection([
            ('issue', u'发行'),  # 默认is_enabled设为不启用
            # 内部操作跟启用相同，默认is_enabled设为启用
            ('warehousing', u'入库'),
            ('enable', u'启用'),
            ('disable', u'禁用'),
            ('discard',u'销毁'),
            ('import', u'导入'),  # 默认is_enabled设为启用
            ('active', u'激活'),
            ('deactive', u'取消激活')
        ], u'操作类型', readonly=False, copy=False, select=True),
    }
    # 添加数据库约束，规定操作批次的字段的名称一定是唯一的。
    _sql_constraints = [('uniq_card_issue_name', 'unique (name)', u'操作批次必须唯一')]
    _defaults = {
        # 根据操作类型和时间的拼接来自动生成
        'name': lambda s, cr, uid, ctx={}: s.pool.get('ir.sequence').next_by_code(cr, uid, ctx.get('default_operation_type'), context=ctx),
        'suffix_val': 8
    }

    def get_exist_codes(self, cr, uid, product_id, number_start, quantity, context=None):
        '''
            传入的是产品、起始券号和数量
            返回的是line表里面存在的券号列表
        '''
        codes = []
        for i in range(quantity):
            codes.append(self.get_next_n_number(cr, number_start, i))
        sql_codes = ','.join(["'%s'" % code for code in codes])
        cr.execute("select issue_id from product_card_line where code in (%s) GROUP BY issue_id" % sql_codes)
        issue_ids = [issue_id[0] for issue_id in cr.fetchall()]
        # if len(issue_ids) > 1:
        #     raise osv.except_osv(
        #         u'警告', u'在同一次操作中,卡券批次必须相同！')
        if product_id == -1:  # only called by issue
            cr.execute(
                "select code from product_card_line where code in (%s)" % sql_codes)
        else:
            cr.execute("select code from product_card_line where code in (%s) and product_id= %d " % (
                sql_codes, product_id))
        res = [ret[0] for ret in cr.fetchall()]
        return res

    def check_code_match(self, cr, uid, product_id, number_start, quantity, context=None):
        '''
            传入的是产品、起始券号和数量
            判断该起始券号是否和该产品相匹配或不存在，返回的是报错信息
        '''
        number_now = number_start
        for i in range(quantity):
            code = self.get_next_n_number(cr, number_now, i)
            cr.execute(
                "select product_id from product_card_line where code = '%s' " % code)
            res = [ret[0] for ret in cr.fetchall()]
            if not res:
                raise osv.except_osv(u'警告', u'卡券' + code + u'不存在，请重新输入！')
            # 当不同产品共用一个卡券号范围时，才会需要判断每个卡券号是否和产品匹配
            elif res[0] != product_id:
                raise osv.except_osv(u'警告', u'您输入的券号' +
                                     code + u'和产品不匹配，请重新输入！')
        return True

    def onchange_number_end(self, cr, uid, ids, operation_type, number_start, quantity,
                            is_suffix, suffix_val, context=None):
        if not number_start or not quantity:
            return {}
        abs_quantity = abs(quantity)
        if is_suffix and operation_type == 'issue':
            if not number_start.endswith(suffix_val):
                return {'value': {'number_start': ""},
                        'warning': {'title': '⚠️警告⚠️', 'message': '输入的券号缺少后缀%s' % (suffix_val)}}

            number_end = self.get_next_n_number(cr, number_start[0: -len(suffix_val)], abs_quantity - 1)
            return {'value': {'number_end': "%s%s" % (number_end, suffix_val)}}  # 取完整结束卡券
        if number_start.endswith(suffix_val) and operation_type == 'issue':
            return {'value': {'number_start': ""},
                    'warning': {'title': '⚠️警告⚠️', 'message': '如果有后缀%s，需要打勾有后缀%s' % (suffix_val, suffix_val)}}
        number_end = self.get_next_n_number(cr, number_start, abs_quantity - 1)
        return {'value': {'number_end': number_end}}  # 取完整结束卡券

        # 此方法就是为了，得到下一个卡券号码。卡券号根据一定的规则自动生成。所以按照生成规则进行解析就可以得到下一个号码。

    def get_next_n_number(self, cr, number_start, n):
        cr.execute("""SELECT pci.suffix_val FROM product_card_line pcl
                             INNER JOIN product_card_issue pci ON pci.id = pcl.issue_id
                             WHERE pcl.code='%s' AND pci.is_suffix=True""" % number_start)
        suffix_list = cr.fetchall()
        if suffix_list:
            suffix_val = suffix_list[0][0]
        else:
            suffix_val = ''
        if suffix_val:
            pre = number_start[0: -len(suffix_val)]
        else:
            pre = number_start
        num, number_start = '', pre
        for i in list(number_start):
            if pre[-1] in list('0123456789'):
                num += pre[-1]
                pre = pre[:-1]
        if not num:
            raise osv.except_osv(u'警告', u'卡号最后一位必须是数字！')
        num = num[::-1]
        num_new = int(num) + n
        res = pre + str(num_new).zfill(len(num))
        if len(res) > len(number_start):
            raise osv.except_osv(u'警告', u'您输入的起始和结束卡券位数不一致，请重新输入！')
        return '%s%s' % (res, suffix_val)

    def product_card_produce(self, cr, uid, ids, context=None):  # 卡券发行
        user_obj = self.pool.get('res.users')
        card_line_obj = self.pool.get('product.card.line')
        card_index_obj = self.pool.get('product.card.index')
        card_track_obj = self.pool.get('product.card.track')
        card_password_obj = self.pool.get('product.card.password')
        for card in self.browse(cr, uid, ids, context=context):
            if not card.product_id.is_card:
                raise osv.except_osv(u'警告', u'选择的产品不是卡券产品！')
            if card.quantity <= 0:
                raise osv.except_osv(u'警告', u'卡券数量必须大于0！')
            # 在卡券发行时，只用校验卡券号码是否存在，而不去匹配产品，所以在这里给product_id传值-1。
            number_now = card.number_start
            card.write({'number_start': card.number_start,
                        'number_end':  card.onchange_number_end(card.operation_type, card.number_start, card.quantity,
                                                                card.is_suffix, card.suffix_val, context=None)['value']['number_end']})
            codes = self.get_exist_codes(
                cr, uid, -1, number_now, card.quantity, context=context)
            if len(codes):
                raise osv.except_osv(
                    u'警告', u'以下券号' + ','.join(codes) + u'已存在，请重新输入！')
            for line in range(card.quantity):
                '''  新增卡券明细  '''
                card_line_id = card_line_obj.create(cr, uid, {
                    'name': 0,
                    'code': number_now,
                    'publish_date': fields.datetime.now(),
                    'product_id': card.product_id.id,
                    'issue_id': card.id,
                    'owner_id': user_obj.browse(cr, uid, uid, context).company_id.partner_id.id,
                }, context=context)
                card_line_obj.write(cr, uid, card_line_id, {
                                    'name': card_line_id, }, context=context)
                '''新增卡券密码表'''
                card_password_obj.create(cr, 1, {
                    'line_id': card_line_id,
                    'password': random.randint(10**(card.product_id.pass_length - 1), 10**card.product_id.pass_length - 1),
                }, context=context)
                '''  新增卡券归属  '''
                card_index_id = card_index_obj.create(cr, uid, {
                    'owner_id': user_obj.browse(cr, uid, uid, context).company_id.partner_id.id,
                    'card_line_id': card_line_id,
                    'code': number_now,
                    'publish_date':fields.datetime.now(),
                    'product_id': card.product_id.id,
                }, context=context)
                '''  新增卡券跟踪  '''
                card_track_id = card_track_obj.create(cr, uid, {
                    'card_line_id': card_line_id,
                    'code': number_now,
                    'publish_date': fields.datetime.now(),
                    'new_owner_id': user_obj.browse(cr, uid, uid, context).company_id.partner_id.id,
                }, context=context)
                number_now = self.pool['product.card.issue'].get_next_n_number(cr, number_now, 1)

        return True

    def product_card_in(self, cr, uid, ids, context=None):  # 入库时更新卡券明细表和卡券状态归属跟踪表记录
        card_line_obj = self.pool.get('product.card.line')
        move_obj = self.pool.get("stock.move")

        for card in self.browse(cr, uid, ids, context=context):
            if card.quantity <= 0:
                raise osv.except_osv(u'警告', u'卡券数量必须大于0！')
            self.check_code_match(
                cr, uid, card.product_id.id, card.number_start, card.quantity)
            card.write({'number_end': card.onchange_number_end(card.operation_type, card.number_start, card.quantity,
                                                                card.is_suffix, card.suffix_val, context=None)['value']['number_end']})

            # 当卡券入库操作后，库存自动增加
            stock_picking_type_obj = self.pool.get("stock.picking.type")
            product_uom_obj = self.pool.get("product.uom")
            picking_type_in_id = stock_picking_type_obj.search(cr, uid, [('name', '=', '接收')], context=context)
            product_uom_id = product_uom_obj.search(cr, uid, [('name', '=', '件')], context=context)
            picking_type_in_obj = stock_picking_type_obj.browse(cr, uid, picking_type_in_id, context=context)[0]  # warehouse_id
            vals = {
                    'product_id': card.product_id.id,
                    'date': fields.datetime.now(),
                    'product_uom_qty': card.quantity,
                    'product_uom': product_uom_id[0],
                    'location_id': picking_type_in_obj.default_location_src_id.id,
                    'location_dest_id': picking_type_in_obj.default_location_dest_id.id,
                    'name': card.product_id.name,
                    }
            new_move_id = move_obj.create(cr, uid, vals, context=context)
            move_obj.action_done(cr, uid, new_move_id, context=context)

            number_now = card.number_start
            for line in range(card.quantity):
                card_line_id = card_line_obj.search(
                    cr, uid, [('code', '=', number_now)], context=context)
                # 标记卡券已入库
                card_line_obj.write(cr, uid, card_line_id, {'is_card_in': True}, context=context)

                card_line = card_line_obj.browse(
                    cr, uid, card_line_id, context=context)
                if card_line.is_enabled:
                    raise osv.except_osv(
                        u'警告', u'卡券' + card_line.code + u'已经启用，请勿重复操作！')
                '''更新卡券明细表,卡券改为启用'''
                card_line_obj.do_enable(cr, uid, card_line_id, context=context)
                number_now = self.pool['product.card.issue'].get_next_n_number(cr, number_now, 1)
        return True

    def product_card_enable(self, cr, uid, ids, context=None):  # 卡券启用操作
        card_line_obj = self.pool.get('product.card.line')

        for card in self.browse(cr, uid, ids, context=context):
            if card.quantity <= 0:
                raise osv.except_osv(u'警告', u'卡券数量必须大于0！')
            self.check_code_match(
                cr, uid, card.product_id.id, card.number_start, card.quantity)
            card.write({'number_end': card.onchange_number_end(card.operation_type, card.number_start, card.quantity,
                                                                card.is_suffix, card.suffix_val, context=None)['value']['number_end']})

            number_now = card.number_start
            for line in range(card.quantity):
                '''从card_line表中得到要操作券号的id列表'''
                card_line_id = card_line_obj.search(
                    cr, uid, [('code', '=', number_now)], context=context)
                card_line = card_line_obj.browse(
                    cr, uid, card_line_id, context=context)

                if not card_line.is_card_in:
                    raise osv.except_osv(u'警告', u'卡券未入库，不能启用！')

                if card_line.is_enabled:
                    raise osv.except_osv(
                        u'警告', u'卡券' + card_line.code + u'已经启用，请勿重复操作！')
                '''更新卡券明细表,卡券状态改为启用'''
                card_line_obj.do_enable(cr, uid, card_line_id, context=context)
                number_now = self.pool['product.card.issue'].get_next_n_number(cr, number_now, 1)
        return True

    def product_card_disable(self, cr, uid, ids, context=None):  # 卡券禁用操作
        card_line_obj = self.pool.get('product.card.line')

        for card in self.browse(cr, uid, ids, context=context):
            if card.quantity <= 0:
                raise osv.except_osv(u'警告', u'卡券数量必须大于0！')
            self.check_code_match(
                cr, uid, card.product_id.id, card.number_start, card.quantity)
            card.write({'number_end': card.onchange_number_end(card.operation_type, card.number_start, card.quantity,
                                                                card.is_suffix, card.suffix_val, context=None)['value']['number_end']})

            number_now = card.number_start
            for line in range(card.quantity):
                card_line_id = card_line_obj.search(
                    cr, uid, [('code', '=', number_now)], context=context)
                card_line = card_line_obj.browse(
                    cr, uid, card_line_id, context=context)
                # if card_line.is_active==True:
                # raise osv.except_osv(u'警告',u'卡券' + card_line.code +
                # u'已经激活，不可禁用！')
                if card_line.is_enabled == False:
                    raise osv.except_osv(
                        u'警告', u'卡券' + card_line.code + u'还未启用，不可禁用！')
                if card_line.is_exchanged == True:
                    raise osv.except_osv(
                        u'警告', u'卡券' + card_line.code + u'已经兑换，不可禁用！')
                '''更新卡券明细表,卡券状态改为禁用'''
                card_line_obj.do_disable(
                    cr, uid, card_line_id, context=context)
                number_now = self.pool['product.card.issue'].get_next_n_number(cr, number_now, 1)
        return True

# 卡券号码密码状态明细表
# 此表普通用户不可导出，授权后才可以导出


class product_card_line(osv.osv):
    _name = "product.card.line"
    _description = u"卡券明细"
    _rec_name = "code"
    _columns = {
        # 默认同odoo自带的主键id，可以修改，内部管理备注使用
        'name': fields.char(u'内部卡号', required=False),
        'code': fields.char(u'卡券编号', required=True, select=True),  # 顺序或者随机生成
        'product_id': fields.many2one('product.product', u'产品编号', required=True, domain="['&',('is_card','=', True),('act_id','!=','')]"),
        'issue_id': fields.many2one('product.card.issue', u'发行批次'),
        'is_code_random': fields.boolean(u'对外号码是否随机生成'),  # 暂不实现
        'is_active': fields.boolean(u'是否激活'),
        'is_enabled': fields.boolean(u'是否启用'),
        'is_exchanged': fields.boolean(u'是否已兑换'),
        # 最后归属partner，一开始归属是发行方(最末级partner)
        'owner_id': fields.many2one('res.partner', u'归属方'),
        'delivery_lock': fields.boolean(u'订单发货锁定'),
        # 标识卡券目前的状态，归属方
        'level_one_partner_id': fields.many2one('res.partner', u'代理商'),
        'level_two_partner_id': fields.many2one('res.partner', u'经销商'),
        'is_electron': fields.boolean(u'是否电子卡券'),
        'is_card_in': fields.boolean(u'卡券是否入库'),
        'publish_date': fields.datetime(u'卡券发行日期'),
        'active': fields.boolean('可用'),
        'is_vip':fields.boolean(u'VIP卡券'),
    }
    _sql_constraints = [('uniq_code', 'unique(code)', u'卡券编号必须唯一')]
    _defaults = {
        'active': True,
    }

    def write(self,cr,uid,ids,vals,context=None):
        for card_line_row in self.browse(cr,uid,ids,context=context):
            if not card_line_row.active:
                raise osv.except_osv(
                    u'警告', u'卡券' + card_line_row.code + u'已经销毁，不能进行操作！')
        return super(product_card_line,self).write(cr,uid,ids,vals,context=context)

    def do_discard(self,cr,uid,ids,context=None):
        card_track_obj = self.pool.get('product.card.track')
        self.write(cr,uid,ids,{'active':False},context=context)
        for card_line in self.browse(cr, uid, ids, context=context):
            card_track_id = card_track_obj.create(cr, uid, {
                'card_line_id': card_line.id,
                'code': card_line.code,
                'publish_date': card_line.publish_date,
                'operation_type': 'discard',
                'changed_field': u'销毁卡券',
                'old_value': '可用',
                'new_value': '销毁',
            }, context=context)
        model_data_obj = self.pool.get('ir.model.data')
        stock_picking_tree_ids = model_data_obj.xmlid_to_res_id(
            cr, SUPERUSER_ID, 'product_card.product_card_line_query_tree')
        return {
            'type': 'ir.actions.act_window',
            'res_model': 'product.card.line',
            'view_mode': 'tree,form',
            'view_type': 'form',
            'name': u'卡券明细查询',
            'views': [(stock_picking_tree_ids, 'tree')],
            'view_id': stock_picking_tree_ids,
        }

    def do_enable(self, cr, uid, ids, context=None):  # 单张卡券启用操作
        card_track_obj = self.pool.get('product.card.track')

        op_type = 'enable'
        if context.get('default_operation_type') == 'warehousing':
            op_type = 'warehousing'
        for card_line in self.browse(cr, uid, ids, context=context):
            '''更新卡券明细表,卡券改为启用'''
            if card_line.is_enabled == True:
                continue
            self.write(cr, uid, card_line.id, {
                       'is_enabled': True, }, context=context)
            card_track_id = card_track_obj.create(cr, uid, {
                'card_line_id': card_line.id,
                'code': card_line.code,
                'publish_date': card_line.publish_date,
                'operation_type': op_type,
                'changed_field': u'是否启用',
                'old_value': '禁用',
                'new_value': '启用',
            }, context=context)

    def do_disable(self, cr, uid, ids, context=None):  # 单张卡券禁用操作
        card_track_obj = self.pool.get('product.card.track')
        for card_line in self.browse(cr, uid, ids, context=context):
            '''更新卡券明细表,卡券改为禁用'''
            # if card_line.is_active==True:
            # raise osv.except_osv(u'警告',u'卡券' + card_line.code +
            # u'已经激活，不可禁用！')
            if card_line.is_enabled == False:
                continue
            self.write(cr, uid, card_line.id, {
                       'is_enabled': False, }, context=context)
            card_track_id = card_track_obj.create(cr, uid, {
                'card_line_id': card_line.id,
                'code': card_line.code,
                'publish_date': card_line.publish_date,
                'operation_type': 'disable',
                'changed_field': u'是否启用',
                'old_value': '启用',
                'new_value': '禁用',
            }, context=context)

    def do_active(self, cr, uid, ids, context=None):  # 多张卡券激活操作
        user_obj = self.pool.get('res.users')
        res_partner_obj = self.pool.get('res.partner')
        card_track_obj = self.pool.get('product.card.track')
        card_index_obj = self.pool.get('product.card.index')
        sale_order_obj = self.pool.get('sale.order')
        order_line_obj = self.pool.get('sale.order.line')
        order_card_obj = self.pool.get('order.card')
        pro_pro_obj = self.pool.get('product.product')
        sum_dict = {}
        owner_ids = []  # 获取券号对应的归属方id列表
        for card_line in self.browse(cr, uid, ids, context=context):
            pro_pro_name = pro_pro_obj.browse(
                cr, uid, card_line.product_id.id, context=context)
            res_partner_name = res_partner_obj.browse(
                cr, uid, card_line.owner_id.id, context)
            if pro_pro_name.list_price == 0:
                raise osv.except_osv(
                    u'警告', u'您输入的卡券产品  <%s> 销售价格为零，不能激活！' % (pro_pro_name.name))
            if card_line.is_active == True:
                return '卡券' + card_line.code + '已激活！'
            if card_line.is_enabled == False:
                return '卡券' + card_line.code + '还未启用不能激活，请先启用！'
            if card_line.owner_id.id == user_obj.browse(cr, uid, uid, context).company_id.partner_id.id:
                return '卡券' + card_line.code + '归属方还是发行方，不可激活!'
            owner_ids.append(card_line.owner_id.id)
            if len(set(owner_ids)) > 1:
                return "卡券归属方不同，不能激活"
            '''更新卡券明细表,卡券改为激活'''
            self.write(cr, uid, card_line.id, {
                       'is_active': True, }, context=context)

            buy_price = self.price_change(
                cr, uid, ids, card_line.owner_id.id, card_line.product_id.id, context=context)
            if buy_price == 0:
                raise osv.except_osv(u'警告', u'您输入的  <归属方为：%s，产品：%s> 的激活价格为零，不能激活！' % (
                    res_partner_name.name, pro_pro_name.name))
            card_track_obj.create(cr, uid, {
                'card_line_id': card_line.id,
                'code': card_line.code,
                'operation_type': 'active',
                'publish_date': card_line.publish_date,
                'changed_field': u'是否激活',
                'old_value': '未激活',
                'new_value': '激活',
                'buy_price': buy_price,
            }, context=context)

            card_index_id = card_index_obj.search(cr, uid, [(
                'card_line_id', '=', card_line.id), ('owner_id', '=', card_line.owner_id.id)], context=context)[0]
            card_index_obj.write(cr, uid, [card_index_id], {
                                 'buy_price': buy_price})

            # 每个owner创建一个销售订单，每个产品创建一个订单行，所以先分组
            # {owner：{product1：qty,product2:qty},owner2:{product1：qty},...}

            if not sum_dict.has_key(card_line.owner_id.id):
                sum_dict[card_line.owner_id.id] = {}
            if not sum_dict[card_line.owner_id.id].has_key(card_line.product_id):
                sum_dict[card_line.owner_id.id].update(
                    {card_line.product_id: [buy_price, 0, []]})
            sum_dict[card_line.owner_id.id][card_line.product_id][1] += 1
            sum_dict[card_line.owner_id.id][
                card_line.product_id][2].append(card_line.id)
        ''' 卡券激活时生成激活服务订单'''
        for oid in sum_dict.keys():
            oc_ids = []
            sale_order_id = sale_order_obj.create(cr, uid, {
                'partner_id': oid,
                'is_card': True,
                'is_active': True,
                'consignee': self.pool.get('res.partner').browse(cr, uid, oid, context).name,
            }, context=context)
            for product in sum_dict[oid].keys():
                order_line_obj.create(cr, uid, {
                    'order_id': sale_order_id,
                    'product_id': product.act_id.id,
                    'product_uom_qty': sum_dict[oid][product][1],
                    'price_unit': sum_dict[oid][product][0],
                }, context=context)
                # 假设：同一个产品的卡券，id相邻则卡号一定相邻。此假设在同一个产品相继发行两次时会出现反例 FIXIT
                res = self.id_get(cr, uid, sorted(
                    sum_dict[oid][product][2]), context=context)
                for key in res.keys():  # 根据返回的res来新建订单券号列表。减少冗余。
                    oc_id = order_card_obj.create(cr, uid, {
                        'order_id': sale_order_id,
                        'picking_id': '',
                        'starting_number': key,
                        'continue_number': res[key],
                        'is_active': True,
                        'amount': res[key] * sum_dict[oid][product][0]
                    }, context=context)
                    oc_ids.append(oc_id)
            sale_order_obj.check_balance(cr, uid, [sale_order_id], context)
            sale_order_obj.signal_workflow(
                cr, 1, [sale_order_id], 'order_confirm')
            # 余额足够，未报错，则标示为已发货
            self.pool.get('order.card').write(cr, SUPERUSER_ID, oc_ids, {'is_shipped': True,
                                                                         'shipped_date': datetime.datetime.now()})
            return ''
    # 此方法主要是为了让零星选中的卡券号码进行分组。如果连续就只记录起始券号和连续数量。此方法是为了方便，为了减少在新建券号列表时的冗余。
    # 偷懒的比较高效的方法，用ID来判断。但是如单独使用存在一定的安全问题。连续卡号中可能存在两种产品

    def id_get(self, cr, uid, ids, context=None):
        res = {}
        start = ids[0]
        next = ids[0]
        continue_number = 1
        for id in ids[1:]:
            if id == next + 1:
                continue_number = continue_number + 1
                next = next + 1
            else:
                res.update({start: continue_number})
                start = id
                next = id
                continue_number = 1
        res.update({start: continue_number})
        return res
    # 在新建销售订单时，订单上的价格要根据查询价格表得来的对应用户的价格。

    def price_change(self, cr, uid, ids, partner_id, product_id, context=None):
        partner = self.pool.get('res.partner').browse(
            cr, uid, partner_id, context=context)
        pricelist = partner.property_product_pricelist and partner.property_product_pricelist.id or False
        price = 0
        if pricelist:
            price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist],
                                                                 product_id, 1.0, partner_id, context=context
                                                                 )[pricelist]
        return price
    # 取消激活操作类似与激活。

    def batch_insert(self, cr, uid, model, fileds, values, context=None):
        vals_length = len(values)
        sql_fileds = ",".join(fileds)
        cycle_number = vals_length / 100
        if vals_length % 100 != 0:
            cycle_number = cycle_number + 1
        for index in xrange(cycle_number):
            if index == cycle_number - 1:
                sql_values = ",".join(values[index * 100:vals_length])
            else:
                sql_values = ",".join(values[index * 100:index * 100 + 100])
            sql = "INSERT INTO %s (%s) VALUES %s;" % (
                model, sql_fileds, sql_values)
            cr.execute(sql)

    def do_deactive(self, cr, uid, ids, context=None):  # 单张卡券取消激活操作
        card_line_obj = self.pool.get('product.card.line')
        card_index_obj = self.pool.get('product.card.index')
        sale_order_obj = self.pool.get('sale.order')
        order_line_obj = self.pool.get('sale.order.line')
        order_card_obj = self.pool.get('order.card')
        sum_dict = {}
        owner_ids, values, card_index_list, card_line_ids = [], [], [], []  # 获取券号对应的归属方id列表
        time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        for card_line in card_line_obj.browse(cr, uid, ids, context=context):
            '''  更新卡券明细表，卡券状态改为未激活    '''
            card_index = card_index_obj.browse(
                cr, uid, card_line.id, context=context)
            if not card_line.is_active:
                return '卡券' + card_line.code + '已处于未激活状态！'
            if not card_line.is_enabled:
                return '卡券' + card_line.code + '还未启用不能取消激活，请先启用！'
            owner_ids.append(card_line.owner_id.id)
            if len(set(owner_ids)) > 1:
                return "卡券归属方不同，不能取消激活"
            if card_line.owner_id != card_line.level_one_partner_id:
                return "卡券已经被代理商销售出去，请让代理商先下激活订单负数订单。"
            # 以前代码感觉不对，影响效率而且没啥特别的意义。
            # cr.execute('''SELECT product_card_line.code
            #                 FROM product_card_line,apply_delivery
            #                 WHERE product_card_line.id = apply_delivery.code''')
            # res = [ret[0] for ret in cr.fetchall()]
            if card_line.is_exchanged:
                return '卡券' + card_line.code + '已提货，不可取消激活'
            card_line_ids.append(card_line.id)

            # 每个owner创建一个销售订单，每个产品创建一个订单行，所以先分组
            # {owner：{product1：qty,product2:qty},owner2:{product1：qty},...}

            if card_line.level_one_partner_id.id not in sum_dict:
                sum_dict[card_line.level_one_partner_id.id] = {}
            if card_line.product_id not in sum_dict[card_line.level_one_partner_id.id]:
                sum_dict[card_line.level_one_partner_id.id].update(
                    {card_line.product_id: [0, []]})
            sum_dict[card_line.level_one_partner_id.id][
                card_line.product_id][0] += 1
            sum_dict[card_line.level_one_partner_id.id][
                card_line.product_id][1].append(card_line.code)
        ''' 卡券取消激活时生成激活服务订单'''
        card_index_id = card_index_obj.search(cr, uid, [(
            'card_line_id', 'in', card_line_ids), ('owner_id', 'in', owner_ids)], order="id desc", context=context)
        product_price_dcit = {}
        for card_index in card_index_obj.browse(
                cr, uid, card_index_id, context=context):
            buy_price = card_index.buy_price
            if card_index.code not in product_price_dcit:G
                product_price_dcit.update({card_index.code: buy_price})
                card_index_list.append(card_index.id)

                values.append("('%s', '%s','deactive', '是否激活', '激活', '未激活', %s,%s,%s,(now() at time zone 'UTC'),(now() at time zone 'UTC'),timestamp'%s')" % (
                    card_index.card_line_id.id, card_index.code, -buy_price, uid, uid, time))

        card_line_obj.write(cr, uid, card_line_ids, {
            'is_active': False}, context=context)

        card_index_obj.write(cr, uid, card_index_list, {
                             'buy_price': 0.00}, context=context)

        insert_field = ["card_line_id", "code",
                        "operation_type", "changed_field", "old_value", "new_value", "buy_price", "create_uid", "write_uid", "create_date", "write_date", "track_time"]
        self.batch_insert(cr, uid, "product_card_track", insert_field,
                          values, context=context)
        for oid in sum_dict.keys():
            sale_order_id = sale_order_obj.create(cr, uid, {
                'partner_id': oid,
                'is_card': True,
                'is_active': True,
                'is_return': True,
                'consignee': self.pool.get('res.partner').browse(cr, uid, oid, context).name,
            }, context=context)
            for product in sum_dict[oid].keys():
                order_line_obj.create(cr, uid, {
                    'order_id': sale_order_id,
                    'product_id': product.act_id.id,
                    'product_uom_qty': -sum_dict[oid][product][0],
                    'price_unit': product_price_dcit.get(sum_dict[oid][product][1][0], 0),
                }, context=context)
                # 假设：同一个产品的卡券，id相邻则卡号一定相邻。此假设在同一个产品相继发行两次时会出现反例 FIXIT
                owner_card_line_ids = card_line_obj.search(
                    cr, uid, [("code", "in", sum_dict[oid][product][1])], context=context)
                res = self.id_get(cr, uid, sorted(
                    owner_card_line_ids), context=context)
                for key in res.keys():
                    order_card_obj.create(cr, uid, {
                        'order_id': sale_order_id,
                        'picking_id': '',
                        'starting_number': key,
                        'continue_number': res[key],
                        'is_active': True,
                        'amount': - res[key] * product_price_dcit.get(sum_dict[oid][product][1][0], 0),
                        'is_shipped': True,
                        'shipped_date': datetime.datetime.now()
                    }, context=context)
            sale_order_obj.signal_workflow(
                cr, 1, [sale_order_id], 'order_confirm')

        return ''
# 新建一个product_card_password表，只给管理员读写建删权限
# 两个字段 line_id,password
# 这样可以避免内外部用户通过网页段读取密码信息


class product_card_password(osv.osv):
    _name = "product.card.password"
    _description = u"卡券明细的密码查询"
    _rec_name = "line_id"
    _columns = {
        # 顺序或者随机生成
        'line_id': fields.many2one('product.card.line', u'卡券编号', required=True, select=True),
        'password': fields.char(u'密码', required=True),  # 密码界面上不可见
    }

# 卡券明细导入临时表
# 此表用于卡券导入入库时，临时保存导入数据的临时表，每次执行导入前全部清空


class product_card_line_load_temp(osv.osv):
    _name = "product.card.line.load.temp"
    _description = u"卡券明细临时导入信息"
    _columns = {
        'code': fields.char(u'卡券编号', required=True, select=True),  # 顺序或者随机生成
    }

# 卡券归属索引表
"""
卡券归属索引：主要是为了方便查找此卡券的归属方，和买入价格。
"""


class product_card_index(osv.osv):
    _name = "product.card.index"
    _description = u'卡券归属索引表'
    _columns = {
        'owner_id': fields.many2one('res.partner', u'归属方'),
        'card_line_id': fields.many2one('product.card.line', u'卡券内部编号'),
        'card_in': fields.related('card_line_id', 'name', string=u'内部卡号', type='char'),
        # 编号冗余字段，便于查询
        'code': fields.char(u'卡券编号', readonly=True, select=True),
        'is_sold_out': fields.boolean(u'是否售出', readonly=True),
        'buy_price': fields.float(u'买入价格', readonly=True),
        'product_id': fields.many2one('product.product', u'产品编号', required=True, domain="['&',('is_card','=', True),('act_id','!=','')]"),
        'publish_date': fields.datetime(u'卡券发行日期')

    }

"""
# 卡券状态、归属变化跟踪表
卡券日志表，主要是为了追踪卡券目前的状态，主要的记录字段有，变化字段。新值，原值，归属方，成交价格，记录时间。

"""


class product_card_track(osv.osv):
    _name = "product.card.track"
    _description = u'卡券日志'
    _columns = {
        'card_line_id': fields.many2one('product.card.line', u'卡券内部编号'),
        'card_in': fields.related('card_line_id', 'name', string=u'内部卡号', type='char', readonly='1'),
        'code': fields.char(u'卡券编号'),
        'operation_type': fields.selection([('issue', u'发行'), ('warehousing', u'入库'),('discard',u'销毁'),
                                            ('enable', u'启用'), ('disable', u'禁用'), ('active',
                                                                                    u'激活'), ('deactive', u'取消激活'),
                                            ('exchange', u'兑换'), ('sold', u'销售'), ('back', u'退回')], u'操作类型'),
        'changed_field': fields.char(u'变化的字段'),  # 用字段中文名
        'old_value': fields.char(u'原值'),
        'new_value': fields.char(u'新值'),
        'old_owner_id': fields.many2one('res.partner', u'原归属方'),
        'new_owner_id': fields.many2one('res.partner', u'新归属方'),
        'buy_price': fields.float(u'成交价格'),  # 冗余价格
        'track_time': fields.datetime(u'记录时间'),
        'publish_date': fields.datetime(u'卡券发行日期')
    }

    _defaults = {
        'track_time': lambda *a: datetime.datetime.now(),  # 设置默认的追踪记录时间。
    }


"""
向导方法：用来辅助在更多里边的激活选项。这个向导主要为了在批量激活时让用户来-确认已选的激活信息，如价格，数量，起始券号。
主要是为了确认操作的信息，核对输入信息的正确性，另外就是返回
"""


class active_wizard(models.TransientModel):
    _name = 'active.wizard'
    _description = u'卡券明细表中选中多条记录进行批量激活'

    def build_code(self, cr, codes):
        '''传入一个某一个产品的卡券编号列表，eg:['a001','a002','a0003','a005','a006']
                                返回的 也是一个列表,eg:['a001~a002','a0003','a005~a006'
                                把连续的卡券编号 分组]'''
        ret = []
        new_codes = sorted(codes)  # 升序排列codes
        new_codes.append('ssss')  # 在列表的最后面插入一个无效的元素，防止下面取值时取不到最后一个元素
        before = ''  # 前一个卡券号
        min = new_codes[0]  # 连续编号中最小的一个卡券号
        qty = 0
        for code in new_codes:
            if before != '' and self.pool['product.card.issue'].get_next_n_number(cr, before, 1) != code:
                # 当前的跟前一个卡券号不连续的情况
                if min == before:
                    ret.append(u'%s (1张)' % before)
                else:
                    ret.append(u'%s ~ %s (%d张)' % (min, before, qty))
                min = code
                qty = 0
            before = code
            qty = qty + 1
        return ret
    '''browse 列表填充字典，通过字典来取产品编号，code,弹窗时显示需要激活的详细券号信息'''

    def fields_view_get(self, cr, uid, view_id=None, view_type='form',
                        context=None, toolbar=False, submenu=False):
        if context is None:
            context = {}
        res = super(active_wizard, self).fields_view_get(
            cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False)
        if context.get('active_model', '') == 'product.card.line':
            is_allow_agent_activete_id = self.pool.get("ir.config_parameter").search(cr, uid,
                                                                                     [('key', '=', 'is_allow_agent_activete')], context=context)
            if is_allow_agent_activete_id:
                is_allow_agent_activete = self.pool.get("ir.config_parameter").browse(
                    cr, uid, is_allow_agent_activete_id, context=context)[0].value
                users = self.pool.get("res.users").browse(
                    cr, uid, uid, context=context)
                if is_allow_agent_activete == "False" and users.has_group("dzx_ext.group_agents"):
                    raise osv.except_osv(_('Warning!'),
                                         u'目前不允许激活操作！')
        return res

    def get_message(self, cr, uid, context=None, line_ids=[]):
        ret = ''
        product_list = []  # 取勾选的产品id列表
        product_dict = {}  # 字典存放取到的产品id列表的数量，对外券号，总价格
        all_qty = 0
        all_total = 0.0
        # group lines by product
        cardLines = []
        owner_name = None
        if(line_ids):
            cardLines = line_ids
        else:
            cardLines = context.get('active_ids')

        for card_line in self.pool['product.card.line'].browse(cr, uid, cardLines, context=context):
            if card_line.product_id.id not in product_list:
                product_list.append(card_line.product_id.id)
                product_dict.update(
                    {card_line.product_id.id: {'qty': 0, 'codes': [], 'subtotal': 0.0}})
            if card_line.is_enabled == False:
                raise osv.except_osv(u'警告！', u'%s号未启用，请重新选择' % card_line.code)
            product_dict[card_line.product_id.id]['qty'] += 1
            product_dict[card_line.product_id.id]['subtotal'] += card_line.price_change(
                card_line.owner_id.id, card_line.product_id.id, context=context)
            product_dict[card_line.product_id.id][
                'codes'].append(card_line.code)
            if not owner_name:
                owner_name = card_line.owner_id.name
            elif owner_name != card_line.owner_id.name:
                raise osv.except_osv(u'警告！', u'%s号属于%s，跟前面的券号属于%s不是同一家' % (
                    card_line.code, card_line.owner_id.name, owner_name))

        for product_id in product_list:
            product = product_dict.get(product_id)
            # product name
            ret += '\n%s  %d张  %.2f元\n' % (
                self.pool.get('product.product').browse(
                    cr, uid, product_id, context).name,
                product['qty'],
                product['subtotal']
            )
            ret += '\n'.join(self.build_code(cr, product['codes']))
            all_qty += product['qty']
            all_total += product['subtotal']
            pro_tem_obj = self.pool.get('product.product').browse(
                cr, uid, product_id, context=context)
            if product['subtotal'] == 0:
                if pro_tem_obj.list_price == 0:
                    raise osv.except_osv(
                        u'警告', u'您输入的卡券产品  <%s> 销售价格为零，不能激活！' % (pro_tem_obj.name))
        # summary
        ret += '\n'
        ret += u'待激活' + str(all_qty) + u'张卡券' + '\n'
        ret += u'卡券属于: ' + owner_name + '\n'
        ret += u'激活卡券总需支付金额: %.2f元' % all_total
        return ret
    _columns = {
        'confirm_message': fields.text(u'激活时确认', readonly=True),
    }
    _defaults = {
        'confirm_message': get_message,
    }

    def do_active(self, cr, uid, ids, context=None):
        message = self.pool['product.card.line'].do_active(
            cr, uid, context.get('active_ids'), context=context)
        if message:
            raise osv.except_osv(u'警告！', message)
        return True
"""
向导方法：用来辅助在更多里边的激活选项。这个向导主要为了在批量激活时让用户来-确认已选的取消激活信息，如价格，数量，起始券号。
"""


class deactive_wizard(models.TransientModel):
    _name = 'deactive.wizard'
    _description = u'卡券明细表中选中多条记录进行批量取消激活'
#    def print_code(self,cr,uid,context=None):
#        code=''
#        for card_line in self.pool['product.card.line'].browse(cr,uid,context.get('active_ids'),context=context):
#            code += card_line.code
#     return code

    def build_code(self, cr, codes):
        '''传入一个某一个产品的卡券编号列表，eg:['a001','a002','a0003','a005','a006']
                                返回的 也是一个列表,eg:['a001~a002','a0003','a005~a006'
                                把连续的卡券编号 分组]'''
        ret = []
        new_codes = sorted(codes)  # 升序排列codes
        new_codes.append('ssss')  # 在列表的最后面插入一个无效的元素，防止下面取值时取不到最后一个元素
        before = ''  # 前一个卡券号
        min = new_codes[0]  # 连续编号中最小的一个卡券号
        qty = 0
        for code in new_codes:
            if before != '' and self.pool['product.card.issue'].get_next_n_number(cr, before, 1) != code:
                # 当前的跟前一个卡券号不连续的情况
                if min == before:
                    ret.append(u'%s (1张)' % before)
                else:
                    ret.append(u'%s ~ %s (%d张)' % (min, before, qty))
                min = code
                qty = 0
            before = code
            qty = qty + 1
        return ret
    '''browse 列表填充字典，通过字典来取产品编号，code，弹窗时显示需要取消激活的详细券号信息'''

    def get_message(self, cr, uid, context=None, line_ids=[]):
        card_index_obj = self.pool.get('product.card.index')
        ret = ''
        product_list = []
        product_dict = {}
        all_qty = 0
        all_total = 0.0
        owner_list = []  # 取归属方的id列表
        # group lines by product
        cardLines = []
        if(line_ids):
            cardLines = line_ids
        else:
            cardLines = context.get('active_ids')

        for card_line in self.pool['product.card.line'].browse(cr, uid, cardLines, context=context):
            if card_line.product_id.id not in product_list:
                product_list.append(card_line.product_id.id)
                product_dict.update(
                    {card_line.product_id.id: {'qty': 0, 'codes': [], 'subtotal': 0.0}})
            product_dict[card_line.product_id.id]['qty'] += 1

            card_index_id = card_index_obj.search(cr, uid, [(
                'card_line_id', '=', card_line.id), ('owner_id', '=', card_line.owner_id.id)], context=context)[0]
            card_index = card_index_obj.browse(
                cr, uid, card_index_id, context=context)
            buy_price = card_index.buy_price

            product_dict[card_line.product_id.id]['subtotal'] += buy_price
            product_dict[card_line.product_id.id][
                'codes'].append(card_line.code)
            # 每次循环取当前卡券号对应的代理商加入列表
            if card_line.level_one_partner_id:
                owner_list.append(card_line.level_one_partner_id)

        set_owner_list = set(owner_list)
        #多个代理商的情况会被之后的逻辑拦截, 所以这里只要取得一个代理商的情况即可
        if len(set_owner_list) == 1:
            owner_names = u'归属代理商: ' + set_owner_list.pop().name + '\n'
        else:
            owner_names = u'还未铺券, 无法进行取消激活\n'

        ret = owner_names

        for product_id in product_list:
            product = product_dict.get(product_id)
            # product name
            ret += '\n%s  %d张  %.2f元\n' % (
                self.pool.get('product.product').browse(
                    cr, uid, product_id, context).name,
                product['qty'],
                product['subtotal']
            )
            ret += '\n'.join(self.build_code(cr, product['codes']))
            all_qty += product['qty']
            all_total += product['subtotal']
        # summary
        ret += '\n'
        ret += u'待取消激活' + str(all_qty) + u'张卡券' + '\n'
        ret += u'取消激活卡券总退还金额: %.2f元' % all_total
        return ret
    _columns = {
        'confirm_message': fields.text(u'取消激活时确认', readonly=True),
    }
    _defaults = {
        'confirm_message': get_message,  # 设置输入信息的确认信息，为判断后返回的信息
    }

    def do_deactive(self, cr, uid, ids, context=None):
        '''继承卡券明细的取消激活按钮,在更多了边可以看待取消激活的按钮'''
        message = self.pool['product.card.line'].do_deactive(
            cr, uid, context.get('active_ids'), context=context)
        if message:
            raise osv.except_osv(u'警告！', message)
        return True
"""
向导方法：用来辅助在更多里边的激活选项。这个向导主要为了在批量激活时让用户来-确认已选的激活信息，如价格，数量，起始券号。
"""


class total_active_wizard(models.TransientModel):
    _name = 'total.active.wizard'
    _description = u'输入一批卡券进行激活操作'
    _columns = {
        'memo': fields.char(u'操作批次'),
        'active_number': fields.text(u'需要激活的卡券'),
        'check_active': fields.text(u'卡券号确认', readonly=False),
    }
    _defaults = {
        'memo': lambda s, cr, uid, ctx={}: s.pool.get('ir.sequence').next_by_code(cr, uid, ctx.get('default_operation_type'), context=ctx),
    }

    def check_active_number(self, cr, uid, ids, active_number, context=None):
        '''on_change校验左边输入的卡券号是否正确，若不正确在右边文本框会提示修改
                      若输入全部正确，这显示需要激活卡券的详情'''
        if active_number:
            card_line_obj = self.pool.get('product.card.line')
            user_obj = self.pool.get('res.users').browse(
                cr, uid, uid, context=context)
            res = ''  # 存放报错提示的字符串
            code_line = ''  # 用来装填校验输入的卡券号无错误之后的提示
            line_ids = []  # 根据一个卡券号取得的id列表
            line_idss = []  # 全部检查通过的卡券id，组成数列
            codes = []  # 从输入的text中，转成tuple后拿到的卡券号列表
            rows_tup = []  # 每个卡券号对应的行号
            owner_list = []  # 取归属方的id列表
            codes.extend(self.parse_text(cr, active_number))
            for i in range(len(codes)):
                code_tup = codes[i][1]  # 券号
                rows_tup = codes[i][0]  # 行号
                line_ids = card_line_obj.search(
                    cr, uid, [('code', '=', code_tup), '|', ('active', '=', False), ('active', '=', True)], context=context)
                if not line_ids:
                    res = '第' + str(rows_tup) + '行' + ',' + \
                        '卡券' + code_tup + '不存在'
                    return {'value': {'check_active': res}}
                for line_id in card_line_obj.browse(cr, uid, line_ids, context=context):
                    if line_id.is_active == True:
                        res = '第' + str(rows_tup) + '行' + ',' + \
                            '卡券' + line_id.code + '已激活'
                        return {'value': {'check_active': res}}
                    if line_id.is_enabled == False:
                        res = '第' + str(rows_tup) + '行' + ',' + \
                            '卡券' + line_id.code + '还未启用不能激活，请先启用！'
                        return {'value': {'check_active': res}}
                    if line_id.owner_id.id == user_obj.company_id.partner_id.id:
                        res = '第' + str(rows_tup) + '行' + ',' + \
                            '卡券' + line_id.code + '归属方还是发行方，不可激活!'
                        return {'value': {'check_active': res}}
                    # 每次循环取当前卡券号对应的归属方id加入列表
                    owner_list.append(line_id.owner_id.id)
                line_idss.extend(line_ids)
            # 对归属方id列表去重，然后计算长度，如果长度大于1说明归属方不同，不能激活
            if len(set(owner_list)) > 1:
                res = '您输入的卡券号不属于同一代理商，请逐一激活'
                return {'value': {'check_active': res}}
            code_line = self.pool['active.wizard'].get_message(
                cr, uid, context=context, line_ids=line_idss)
            if len(line_idss) != len(list(set(line_idss))):
                return {'value': {'check_active': u'输入的券号有重复，请核对后在进行操作！'}}
            return {'value': {'check_active': code_line}}

    def parse_text(self, cr, text):
        '''将文本解析为独立的code'''
        text = text.replace(
            ' ', '')  # 之后的几个替换主要是为了，防止用户不清楚解析规则胡乱输入分割的字符。把几个常见的不规范的字符替换成我们规定的能解析的字符。
        text = text.replace('-', '~')
        text = text.replace('－', '~')
        text = text.replace('～', '~')
        mis = 0  # 记录左侧text输入的卡券号所在
        res = []  # 存放解析出来的tuple列表，tuple第一个元素为行号，第二个元素为卡券号
        temp_list = text.split('\n')
        for temp in temp_list:
            row_code = 0  # 用来记录卡券区间一共包含多少张卡券
            mis += 1
            from_to = temp.split('~')
            current = from_to[0]
            res.append((mis, current))
            if len(from_to) == 2:
                while current != from_to[1]:
                    current = self.pool[
                        'product.card.issue'].get_next_n_number(cr, current, 1)
                    res.append((mis, current))
                    row_code += 1
                    # 性能 报错
                    if len(current) != len(from_to[1]):
                        raise osv.except_osv(
                            u'警告', u'您输入的第%s行起始和结束卡券位数不一致，请重新输入！' % mis)
                    if current > from_to[1]:
                        raise osv.except_osv(
                            u'警告', u'您输入的第%s行起始卡券号大于结束卡券号，请重新输入！' % mis)
                    if row_code > 999:
                        raise osv.except_osv(
                            u'警告', u'您输第%s行卡券区间超过1000，请修改后再激活！' % mis)
        return res

    def product_card_active(self, cr, uid, ids, context=None):  # 卡券激活操作
        card_line_obj = self.pool.get('product.card.line')
        line_ids = []
        com_text = self.browse(cr, uid, ids, context=context)
        text_list = com_text.check_active.split('\n')
        if len(text_list[0]) != 0:
            raise osv.except_osv(u'警告', u'您输入的券号有误，请修改正确后再激活！')
        codes = []
        codes.extend([x[1] for x in self.parse_text(cr, com_text.active_number)])
        line_ids.extend(card_line_obj.search(
            cr, uid, [('code', 'in', codes), '|', ('active', '=', False), ('active', '=', True)], context=context))
        card_line_obj_one = card_line_obj.browse(
            cr, uid, line_ids[0], context=context)
        message = self.pool['product.card.line'].do_active(
            cr, uid, line_ids, context=context)
        self.pool.get('product.card.issue').create(cr, uid, {'name': com_text.memo, 'product_id': card_line_obj_one.product_id.id,
                                                             'number_start': " ", 'number_end': "  ",
                                                             'quantity': len(codes),
                                                             'card_list': com_text.active_number, 'operation_type': 'active'}, context=context)
        if message:
            raise osv.except_osv(u'警告！', message)
        return True


class enable_wizard(models.TransientModel):
    _name = 'enable.wizard'

    def build_code(self, cr, codes):
        '''传入一个某一个产品的卡券编号列表，eg:['a001','a002','a0003','a005','a006']
                                返回的 也是一个列表,eg:['a001~a002','a0003','a005~a006'
                                把连续的卡券编号 分组]'''
        ret = []
        new_codes = sorted(codes)  # 升序排列codes
        new_codes.append('ssss')  # 在列表的最后面插入一个无效的元素，防止下面取值时取不到最后一个元素
        before = ''  # 前一个卡券号
        min = new_codes[0]  # 连续编号中最小的一个卡券号
        qty = 0
        for code in new_codes:
            if before != '' and self.pool['product.card.issue'].get_next_n_number(cr, before, 1) != code:
                # 当前的跟前一个卡券号不连续的情况
                if min == before:
                    ret.append(u'%s (1张)' % before)
                else:
                    ret.append(u'%s ~ %s (%d张)' % (min, before, qty))
                min = code
                qty = 0
            before = code
            qty = qty + 1
        return ret

    def get_message(self, cr, uid, context=None, line_ids=[]):
        ret = ''
        product_list = []
        product_dict = {}
        all_qty = 0
        cardLines = []
        if(line_ids):
            cardLines = line_ids
        else:
            cardLines = context.get('active_ids')
        for card_line in self.pool['product.card.line'].browse(cr, uid, cardLines, context=context):
            if not card_line.is_enabled:
                raise osv.except_osv(u'警告！', card_line.code + u"号卡券还未启用无法禁用")
            if card_line.is_exchanged:
                raise osv.except_osv(u'警告！', card_line.code + u"号卡券已被兑换无法禁用")
            if card_line.product_id.id not in product_list:
                product_list.append(card_line.product_id.id)
                product_dict.update(
                    {card_line.product_id.id: {'qty': 0, 'codes': []}})
            product_dict[card_line.product_id.id]['qty'] += 1
            product_dict[card_line.product_id.id][
                'codes'].append(card_line.code)
        for product_id in product_list:
            product = product_dict.get(product_id)
            # product name
            ret += '\n%s  %d张  \n' % (
                self.pool.get('product.product').browse(
                    cr, uid, product_id, context).name,
                product['qty']
            )
            ret += '\n'.join(self.build_code(cr, product['codes']))
            all_qty += product['qty']
        ret += '\n'
        ret += u'待禁用' + str(all_qty) + u'张卡券' + '\n'
        return ret

    _description = u'卡券明细表中选中多条记录进行批量禁用'

    _columns = {
        'confirm_message': fields.text(u'批量禁用确认', readonly=True),
    }

    _defaults = {
        'confirm_message': get_message,
    }

    #卡券明细批量禁用向导确认批量禁用
    def do_disable(self, cr, uid, ids, context=None):
        active_ids = context.get('active_ids')
        if active_ids:
            card_line_obj = self.pool["product.card.line"]
            card_line_obj.do_disable(cr, uid, active_ids)
            return True
        else:
            return False

"""
向导方法：用来辅助在更多里边的禁用选项。这个向导主要为了在批量禁用时让用户来-确认已选的禁用信息，如数量，起始券号。
"""


class total_disable_wizard(models.TransientModel):
    _name = 'total.disable.wizard'
    _description = u'输入一批卡券进行禁用操作'
    _columns = {
        'memo': fields.char(u'操作批次'),
        'disable_number': fields.text(u'需要禁用的卡券'),
        'check_disable': fields.text(u'卡券号确认', readonly=False),
        'is_ignore_disable_card':fields.boolean(u'忽略已禁用的卡券')
    }
    _defaults = {
        'memo': lambda s, cr, uid, ctx={}: s.pool.get('ir.sequence').next_by_code(cr, uid, ctx.get('default_operation_type'), context=ctx),
    }
    def get_message(self, cr, uid, is_ignore_disable_card,context=None, line_ids=[]):
        ret = ''
        product_list = []
        product_dict = {}
        all_qty = 0
        cardLines = []
        if (line_ids):
            cardLines = line_ids
        else:
            cardLines = context.get('active_ids')
        for card_line in self.pool['product.card.line'].browse(cr, uid, cardLines, context=context):
            if not card_line.is_enabled and not is_ignore_disable_card:
                raise osv.except_osv(u'警告！', card_line.code + u"号卡券还未启用无法禁用")
            if card_line.is_exchanged:
                raise osv.except_osv(u'警告！', card_line.code + u"号卡券已被兑换无法禁用")
            if card_line.product_id.id not in product_list:
                product_list.append(card_line.product_id.id)
                product_dict.update(
                    {card_line.product_id.id: {'qty': 0, 'codes': []}})
            product_dict[card_line.product_id.id]['qty'] += 1
            product_dict[card_line.product_id.id][
                'codes'].append(card_line.code)
        for product_id in product_list:
            product = product_dict.get(product_id)
            # product name
            ret += '\n%s  %d张  \n' % (
                self.pool.get('product.product').browse(
                    cr, uid, product_id, context).name,
                product['qty']
            )
            ret += '\n'.join(self.pool.get("enable.wizard").build_code(cr, product['codes']))
            all_qty += product['qty']
        ret += '\n'
        ret += u'待禁用' + str(all_qty) + u'张卡券' + '\n'
        return ret


    def check_disable_number(self, cr, uid, ids, disable_number, is_ignore_disable_card,context=None):
        '''on_change校验左边输入的卡券号是否正确，若不正确在右边文本框会提示修改
                      若输入全部正确，这显示需要禁用卡券的详情'''
        if disable_number:
            card_line_obj = self.pool.get('product.card.line')
            user_obj = self.pool.get('res.users').browse(
                cr, uid, uid, context=context)
            res = ''  # 存放报错提示的字符串
            code_line = ''  # 用来装填校验输入的卡券号无错误之后的提示
            line_ids = []  # 根据一个卡券号取得的id列表
            line_idss = []  # 全部检查通过的卡券id，组成数列
            codes = []  # 从输入的text中，转成tuple后拿到的卡券号列表
            rows_tup = []  # 每个卡券号对应的行号
            owner_list = [] #归属方
            codes.extend(self.parse_text(cr, disable_number))
            for i in range(len(codes)):
                code_tup = codes[i][1]  # 券号
                rows_tup = codes[i][0]  # 行号
                domain = [('code', '=', code_tup)]
                line_ids = card_line_obj.search(cr, uid,domain, context=context) #
                if not line_ids and not is_ignore_disable_card:
                    res = 'ERROR\n第' + str(rows_tup) + '行' + ',' + \
                        '卡券' + code_tup + '不存在'
                    return {'value': {'check_disable': res}}
                for line_id in card_line_obj.browse(cr, uid, line_ids, context=context):
                    if line_id.is_enabled == False and not is_ignore_disable_card:
                        res = 'ERROR\n第' + str(rows_tup) + '行' + ',' + \
                            '卡券' + line_id.code + '还未启用不能禁用，请先启用！'
                        return {'value': {'check_disable': res}}
                    if line_id.is_exchanged == True:
                        res = 'ERROR\n第' + str(rows_tup) + '行' + ',' + \
                            '卡券' + line_id.code + '已经兑换不能禁用，请重新操作！'
                        return {'value': {'check_disable': res}}
                    # 每次循环取当前卡券号对应的代理商加入列表
                    if line_id.level_one_partner_id:
                        owner_list.append(line_id.level_one_partner_id)
                line_idss.extend(line_ids)
            set_owner_list = set(owner_list)
            if len(set_owner_list) > 1:
                owner_names = u'代理商超过1个, 最好核对一下卡号, 目前没有限制多个代理商的卡券一起禁用, 代理商如下:\n'
                while set_owner_list:
                    owner_names += set_owner_list.pop().name + '\n'
            elif len(set_owner_list) == 1:
                owner_names = u'归属代理商: ' + set_owner_list.pop().name + '\n'
            else:
                owner_names = u'还未铺券, 最好不要禁用操作, 如果需要销毁, 请用批量销毁\n'
            code_line = self.get_message(
                cr, uid, is_ignore_disable_card, context=context, line_ids=line_idss)
            return {'value': {'check_disable': owner_names + code_line}}

    def parse_text(self, cr, text):
        '''将文本解析为独立的code'''
        text = text.replace(
            ' ', '')  # 之后的几个替换主要是为了，防止用户不清楚解析规则胡乱输入分割的字符。把几个常见的不规范的字符替换成我们规定的能解析的字符。
        text = text.replace('-', '~')
        text = text.replace('－', '~')
        text = text.replace('～', '~')
        mis = 0  # 记录左侧text输入的卡券号所在
        res = []  # 存放解析出来的tuple列表，tuple第一个元素为行号，第二个元素为卡券号
        temp_list = text.split('\n')
        for temp in temp_list:
            row_code = 0  # 用来记录卡券区间一共包含多少张卡券
            mis += 1
            from_to = temp.split('~')
            current = from_to[0]
            res.append((mis, current))
            if len(from_to) == 2:
                while current != from_to[1]:
                    current = self.pool[
                        'product.card.issue'].get_next_n_number(cr, current, 1)
                    res.append((mis, current))
                    row_code += 1
                    # 性能 报错
                    if len(current) != len(from_to[1]):
                        raise osv.except_osv(
                            u'警告', u'您输入的第%s行起始和结束卡券位数不一致，请重新输入！' % mis)
                    if current > from_to[1]:
                        raise osv.except_osv(
                            u'警告', u'您输入的第%s行起始卡券号大于结束卡券号，请重新输入！' % mis)
                    if row_code > 999:
                        raise osv.except_osv(
                            u'警告', u'您输第%s行卡券区间超过1000，请修改后再继续操作！' % mis)
        return res

    def product_card_disable(self, cr, uid, ids, context=None):  # 卡券激活操作
        card_line_obj = self.pool.get('product.card.line')
        line_ids = []
        com_text = self.browse(cr, uid, ids, context=context)
        error_text_point = com_text.check_disable.find('ERROR')
        if error_text_point >= 0:
            raise osv.except_osv(u'警告', u'您输入的券号有误，请修改正确后再禁用！')
        codes = []
        codes.extend([x[1] for x in self.parse_text(cr, com_text.disable_number)])
        # 批量禁用，调用product_card_line的do_disable方法
        all_code_ids = card_line_obj.search(
            cr, uid, [('code', 'in', codes)], context=context)
        card_line_obj.do_disable(cr, uid, all_code_ids, context=None)
        # 批量操作表中记录操作记录
        all_code_obj = card_line_obj.browse(
            cr, uid, all_code_ids, context=context)
        self.pool.get('product.card.issue').create(cr, uid, {'name': com_text.memo, 'product_id': all_code_obj[0].product_id.id,
                                                             'number_start': " ", 'number_end': "  ",
                                                             'quantity': len(all_code_ids),
                                                             'card_list': com_text.disable_number, 'operation_type': 'disable'}, context=context)
        return True


class total_deactive_wizard(models.TransientModel):
    _name = 'total.deactive.wizard'
    _description = u'输入一批卡券进行取消激活操作'
    _columns = {
        'memo': fields.char(u'操作批次'),
        'deactive_number': fields.text(u'需要取消激活的卡券'),
        'check_deactive': fields.text(u'卡券号确认', readonly=False),
    }
    _defaults = {
        'memo': lambda s, cr, uid, ctx={}: s.pool.get('ir.sequence').next_by_code(cr, uid, ctx.get('default_operation_type'), context=ctx),
    }

    def check_deactive_number(self, cr, uid, ids, deactive_number, context=None):
        '''on_change校验左边输入的卡券号是否正确，若不正确在右边文本框会提示修改
                      若输入全部正确，这显示需要取消激活卡券的详情'''
        if deactive_number:
            card_line_obj = self.pool.get('product.card.line')
            user_obj = self.pool.get('res.users').browse(
                cr, uid, uid, context=context)
            res = ''  # 存放报错提示的字符串
            code_line = ''  # 用来装填校验输入的卡券号无错误之后的提示
            line_ids = []  # 根据一个卡券号取得的id列表
            line_idss = []  # 全部检查通过的卡券id，组成数列
            codes = []  # 从输入的text中，转成tuple后拿到的卡券号列表
            rows_tup = []  # 每个卡券号对应的行号
            owner_list = []  # 取归属方的id列表
            codes.extend(self.pool.get(
                'total.disable.wizard').parse_text(cr, deactive_number))
            for i in range(len(codes)):
                code_tup = codes[i][1]  # 券号
                rows_tup = codes[i][0]  # 行号
                line_ids = card_line_obj.search(
                    cr, uid, [('code', '=', code_tup), '|', ('active', '=', False), ('active', '=', True)], context=context)
                if not line_ids:
                    res = 'ERROR: 第' + str(rows_tup) + '行' + ',' + \
                        '卡券' + code_tup + '不存在'
                    return {'value': {'check_deactive': res}}
                for line_id in card_line_obj.browse(cr, uid, line_ids, context=context):
                    if line_id.do_enable == False:
                        res = 'ERROR: 第' + str(rows_tup) + '行' + ',' + \
                            '卡券' + line_id.code + '未启用'
                        return {'value': {'check_deactive': res}}

                    if line_id.is_active == False:
                        res = 'ERROR: 第' + str(rows_tup) + '行' + ',' + \
                            '卡券' + line_id.code + '未激活'
                        return {'value': {'check_deactive': res}}

                    if line_id.is_exchanged:
                        res = 'ERROR: 第' + str(rows_tup) + '行' + ',' + \
                            '卡券' + line_id.code + '已兑换'
                        return {'value': {'check_deactive': res}}

                        # 每次循环取当前卡券号对应的归属方id加入列表
                    owner_list.append(line_id.owner_id)
                line_idss.extend(line_ids)
                # 对归属方id列表去重，然后计算长度，如果长度大于1说明归属方不同，不能激活
                if len(set(owner_list)) > 1:
                    card_line_id = card_line_obj.search(
                        cr, SUPERUSER_ID, [('id', 'in', line_idss), ('owner_id', '=', line_id.owner_id.id),
                                           '|', ('active', '=', False), ('active', '=', True)], context=context)
                    card_line = card_line_obj.browse(
                        cr, SUPERUSER_ID, card_line_id, context=context)[0]
                    users_id = self.pool.get('res.partner').browse(
                        cr, SUPERUSER_ID, line_id.owner_id.id, context=context)
                    res = 'ERROR: 您输入的卡券号%s属于代理商"%s"，和前面的卡券所属代理商"%s"不同，请逐一取消激活' % (
                        card_line.code, users_id.name, owner_list[0].name)
                    return {'value': {'check_deactive': res}}
            code_line = self.pool['deactive.wizard'].get_message(
                cr, uid, context=context, line_ids=line_idss)
            if len(line_idss) != len(list(set(line_idss))):
                return {'value': {'check_deactive': u'输入的券号有重复，请核对后在进行操作！'}}
            return {'value': {'check_deactive': code_line}}

    def product_card_deactive(self, cr, uid, ids, context=None):  # 卡券激活操作
        card_line_obj = self.pool.get('product.card.line')
        line_ids = []
        com_text = self.browse(cr, uid, ids, context=context)
        error_text_point = com_text.check_deactive.find('ERROR')
        #if error_text_point > 0:
        #text_list = com_text.check_deactive.split('\n')
        #if len(text_list[0]) != 0:
        if error_text_point >= 0:
            raise osv.except_osv(u'警告', u'您输入的券号有误，请修改正确后再取消激活！')
        codes = []
        codes.extend([x[1] for x in self.pool.get(
            'total.disable.wizard').parse_text(cr, com_text.deactive_number)])
        line_ids.extend(card_line_obj.search(
            cr, uid, [('code', 'in', codes), '|', ('active', '=', False), ('active', '=', True)], context=context))
        card_line_obj_one = card_line_obj.browse(
            cr, uid, line_ids[0], context=context)
        message = self.pool['product.card.line'].do_deactive(
            cr, uid, line_ids, context=context)
        self.pool.get('product.card.issue').create(cr, uid, {'name': com_text.memo, 'product_id': card_line_obj_one.product_id.id,
                                                             'number_start': " ", 'number_end': "  ",
                                                             'quantity': len(codes),
                                                             'card_list': com_text.deactive_number, 'operation_type': 'deactive'}, context=context)
        if message:
            raise osv.except_osv(u'警告！', message)
        return True


class total_discard_wizard(models.TransientModel):
    _name = 'total.discard.wizard'
    _description = u'输入一批卡券进行销毁操作'
    _columns = {
        'memo': fields.char(u'操作批次'),
        'discard_number': fields.text(u'需要销毁的卡券'),
        'check_discard': fields.text(u'卡券号确认', readonly=False),
    }
    _defaults = {
        'memo': lambda s, cr, uid, ctx={}: s.pool.get('ir.sequence').next_by_code(cr, uid, ctx.get('default_operation_type'), context=ctx),
    }

    def check_discard_number(self, cr, uid, ids, discard_number, context=None):
        '''on_change校验左边输入的卡券号是否正确，若不正确在右边文本框会提示修改
                      若输入全部正确，这显示需要禁用卡券的详情'''
        if discard_number:
            card_line_obj = self.pool.get('product.card.line')
            user_obj = self.pool.get('res.users').browse(
                cr, uid, uid, context=context)
            line_idss = []  # 全部检查通过的卡券id，组成数列
            codes = []  # 从输入的text中，转成tuple后拿到的卡券号列表
            codes.extend(self.parse_text(cr, discard_number))
            for i in range(len(codes)):
                code_tup = codes[i][1]  # 券号
                rows_tup = codes[i][0]  # 行号
                line_ids = card_line_obj.search(
                    cr, uid, [('code', '=', code_tup), '|', ('active', '=', False), ('active', '=', True)], context=context)
                if not line_ids:
                    res = '第' + str(rows_tup) + '行' + ',' + \
                        '卡券' + code_tup + '不存在'
                    return {'value': {'check_discard': res}}
                for line_id in card_line_obj.browse(cr, uid, line_ids, context=context):
                    if line_id.is_active == True:
                        res = '第' + str(rows_tup) + '行' + ',' + \
                            '卡券' + line_id.code + '券号已激活，不能直接销毁，请先取消激活！'
                        return {'value': {'check_discard': res}}
                    # 每次循环取当前卡券号对应的归属方id加入列表
                line_idss.extend(line_ids)
            code_line = "\n 本次销毁%s张卡券,此操作不能恢复,请慎重操作！"%(len(line_idss))
            return {'value': {'check_discard': code_line}}

    def parse_text(self, cr, text):
        '''将文本解析为独立的code'''
        text = text.replace(
            ' ', '')  # 之后的几个替换主要是为了，防止用户不清楚解析规则胡乱输入分割的字符。把几个常见的不规范的字符替换成我们规定的能解析的字符。
        text = text.replace('-', '~')
        text = text.replace('－', '~')
        text = text.replace('～', '~')
        mis = 0  # 记录左侧text输入的卡券号所在
        res = []  # 存放解析出来的tuple列表，tuple第一个元素为行号，第二个元素为卡券号
        temp_list = text.split('\n')
        for temp in temp_list:
            row_code = 0  # 用来记录卡券区间一共包含多少张卡券
            mis += 1
            from_to = temp.split('~')
            current = from_to[0]
            res.append((mis, current))
            if len(from_to) == 2:
                while current != from_to[1]:
                    current = self.pool[
                        'product.card.issue'].get_next_n_number(cr, current, 1)
                    res.append((mis, current))
                    row_code += 1
                    # 性能 报错
                    if len(current) != len(from_to[1]):
                        raise osv.except_osv(
                            u'警告', u'您输入的第%s行起始和结束卡券位数不一致，请重新输入！' % mis)
                    if current > from_to[1]:
                        raise osv.except_osv(
                            u'警告', u'您输入的第%s行起始卡券号大于结束卡券号，请重新输入！' % mis)
                    if row_code > 999:
                        raise osv.except_osv(
                            u'警告', u'您输第%s行卡券区间超过1000，请修改后再继续操作！' % mis)
        return res

    def product_card_discard(self, cr, uid, ids, context=None):
        card_line_obj = self.pool.get('product.card.line')
        line_ids = []
        com_text = self.browse(cr, uid, ids, context=context)
        text_list = com_text.check_discard.split('\n')
        if len(text_list[0]) != 0:
            raise osv.except_osv(u'警告', u'您输入的券号有误，请修改正确后再销毁卡券！')
        codes = []
        codes.extend([x[1] for x in self.parse_text(cr, com_text.discard_number)])
        # 批量销毁，调用product_card_line的do_disable方法
        all_code_ids = card_line_obj.search(
            cr, uid, [('code', 'in', codes)], context=context)
        card_line_obj.do_discard(cr, uid, all_code_ids, context=None)
        # 批量操作表中记录操作记录
        all_code_obj = card_line_obj.browse(
            cr, uid, all_code_ids, context=context)
        self.pool.get('product.card.issue').create(cr, uid, {'name': com_text.memo, 'product_id': all_code_obj[0].product_id.id,
                                                             'number_start': " ", 'number_end': "  ",
                                                             'quantity': len(all_code_ids),
                                                             'card_list': com_text.discard_number, 'operation_type': 'discard'}, context=context)
        return True

class total_is_vip_mananger_wizard(models.TransientModel):
    _name = 'total.is.vip.mananger.wizard'
    _description = u'输入一批卡券进行销毁操作'
    _columns = {
        'select_num': fields.float(u'选中的条数'),
    }
    _defaults = {
        'select_num': lambda s, cr, uid, ctx={}: len(ctx.get('active_ids',[])),
    }

    def set_card_to_vip(self, cr, uid, ids, context=None):
        self.pool.get('product.card.line').write(cr, SUPERUSER_ID, context.get('active_ids'), {'is_vip': True}, context=context)
        return True

    def remove_card_vip(self, cr, uid, ids, context=None):
        self.pool.get('product.card.line').write(cr, SUPERUSER_ID, context.get('active_ids'), {'is_vip': False}, context=context)
        return True
